package com.cleaningcloud.cld.service.impl;

import com.cleaningcloud.cld.domain.CldMaterialAllocate;
import com.cleaningcloud.cld.domain.dto.CldMaterialAllocateDto;
import com.cleaningcloud.cld.domain.vo.CldMaterialAllocateDetailsVo;
import com.cleaningcloud.cld.domain.vo.CldMaterialAllocateVo;
import com.cleaningcloud.cld.mapper.CldMaterialAllocateDetailsMapper;
import com.cleaningcloud.cld.mapper.CldMaterialAllocateMapper;
import com.cleaningcloud.cld.service.ICldMaterialAllocateService;
import com.cleaningcloud.common.core.constant.SecurityConstants;
import com.cleaningcloud.common.core.utils.DateUtils;
import com.cleaningcloud.common.core.utils.StringUtils;
import com.cleaningcloud.common.core.utils.UniqueIdUtils;
import com.cleaningcloud.common.security.utils.CommunityTypeConversionUtils;
import com.cleaningcloud.common.security.utils.SecurityUtils;
import com.cleaningcloud.erp.api.RemoteCommodityService;
import com.cleaningcloud.erp.api.RemoteWareService;
import com.cleaningcloud.erp.api.domain.ErpCommodityStockAlter;
import com.cleaningcloud.erp.api.domain.ErpWareCommodityNumber;
import com.cleaningcloud.erp.api.utils.StockCommodityAlterUtils;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;

/**
 * 物资调拨Service业务层处理
 *
 * @author cleaningcloud
 * @date 2024-10-28
 */
@Service
public class CldMaterialAllocateServiceImpl implements ICldMaterialAllocateService {
    @Autowired
    private CldMaterialAllocateMapper cldMaterialAllocateMapper;

    @Autowired
    private CldMaterialAllocateDetailsMapper cldMaterialAllocateDetailsMapper;

    @Autowired
    private RemoteWareService remoteWareService;

    @Autowired
    private RemoteCommodityService remoteCommodityService;

    /**
     * 查询物资调拨
     *
     * @param materialAllocateId 物资调拨主键
     * @return 物资调拨
     */
    @Override
    public CldMaterialAllocateVo selectCldMaterialAllocateByMaterialAllocateId(Long materialAllocateId) {
        CldMaterialAllocateVo cldMaterialAllocateVo = cldMaterialAllocateMapper.selectCldMaterialAllocateByMaterialAllocateId(materialAllocateId);
        for (CldMaterialAllocateDetailsVo materialAllocateDetails : cldMaterialAllocateVo.getDetailsList()) {
            materialAllocateDetails.setCommodityType(CommunityTypeConversionUtils.conversion(materialAllocateDetails.getCommodityType()));
        }
        return cldMaterialAllocateVo;
    }

    /**
     * 查询物资调拨列表
     *
     * @param cldMaterialAllocate 物资调拨
     * @return 物资调拨
     */
    @Override
    public List<CldMaterialAllocateVo> selectCldMaterialAllocateList(CldMaterialAllocate cldMaterialAllocate) {
        return cldMaterialAllocateMapper.selectCldMaterialAllocateList(cldMaterialAllocate);
    }

    @Override
    public List<CldMaterialAllocateVo> selectCldUseList(CldMaterialAllocateDto cldMaterialAllocate) {
        List<CldMaterialAllocateVo> list = cldMaterialAllocateMapper.selectCldUseList(cldMaterialAllocate);
        for (CldMaterialAllocateVo cldMaterialAllocateVo : list) {
            for (CldMaterialAllocateDetailsVo cldMaterialAllocateDetailsVo : cldMaterialAllocateVo.getDetailsList()) {
                cldMaterialAllocateDetailsVo.setCommodityType(CommunityTypeConversionUtils.conversion(cldMaterialAllocateDetailsVo.getCommodityType()));
            }
        }
        return list;
    }

    /**
     * 新增物资调拨
     *
     * @param cldMaterialAllocate 物资调拨
     * @return 结果
     */
    @Override
    @Transactional
    public int insertCldMaterialAllocate(CldMaterialAllocateDto cldMaterialAllocate) {
        cldMaterialAllocate.setApproveStatus(cldMaterialAllocate.getApproveStatus() == null ? 0 : cldMaterialAllocate.getApproveStatus());
        cldMaterialAllocate.setCreateTime(DateUtils.getNowDate());
        cldMaterialAllocate.setCreateId(SecurityUtils.getUserId());
        cldMaterialAllocate.setCreateName(SecurityUtils.getUsername());
        cldMaterialAllocate.setFlag(0L);
        cldMaterialAllocate.setIsConfirm(cldMaterialAllocate.getIsConfirm() == null ? 0L : cldMaterialAllocate.getIsConfirm());
        cldMaterialAllocate.setMaterialAllocateDate(cldMaterialAllocate.getMaterialAllocateDate() == null ? DateUtils.getNowDate() : cldMaterialAllocate.getMaterialAllocateDate());
        cldMaterialAllocate.setMaterialOdd(StringUtils.isEmpty(cldMaterialAllocate.getMaterialOdd()) ? "DB" + UniqueIdUtils.generateUniqueId() : cldMaterialAllocate.getMaterialOdd());
        // 调出人
        cldMaterialAllocate.setMaterialOutPerson(cldMaterialAllocate.getMaterialOutPerson() == null ? SecurityUtils.getUserId() : cldMaterialAllocate.getMaterialOutPerson());
        // 调入人
        cldMaterialAllocate.setMaterialInPerson(cldMaterialAllocate.getMaterialInPerson() == null ? SecurityUtils.getUserId() : cldMaterialAllocate.getMaterialInPerson());
        cldMaterialAllocateMapper.insertCldMaterialAllocate(cldMaterialAllocate);
        if (cldMaterialAllocate.getDetailsList() != null && !cldMaterialAllocate.getDetailsList().isEmpty()) {
            cldMaterialAllocate.getDetailsList().forEach(item -> {
                item.setMaterialwareAllocateId(cldMaterialAllocate.getMaterialAllocateId());
            });
            cldMaterialAllocateMapper.batchInsertWareAllocateDetails(cldMaterialAllocate.getDetailsList());
        }
        // 项目申请审核通过
        if (cldMaterialAllocate.getApproveStatus() == 1) {
            auditCldMaterialAllocate(cldMaterialAllocate);
        }
        return 1;
    }


    /**
     * 修改物资调拨
     *
     * @param cldMaterialAllocate 物资调拨
     * @return 结果
     */
    @Override
    @Transactional
    public int updateCldMaterialAllocate(CldMaterialAllocateDto cldMaterialAllocate) {
        cldMaterialAllocate.setApproveStatus(0L);
        cldMaterialAllocateMapper.updateCldMaterialAllocate(cldMaterialAllocate);
        // 先删除物资调拨明细
        cldMaterialAllocateMapper.deleteWareAllocateDetailsByWareAllocateId(cldMaterialAllocate.getMaterialAllocateId());
        if (cldMaterialAllocate.getDetailsList() != null && !cldMaterialAllocate.getDetailsList().isEmpty()) {
            cldMaterialAllocate.getDetailsList().forEach(item -> {
                item.setMaterialwareAllocateId(cldMaterialAllocate.getMaterialAllocateId());
            });
            cldMaterialAllocateMapper.batchInsertWareAllocateDetails(cldMaterialAllocate.getDetailsList());
        }
        return 1;
    }

    @Override
    @Transactional
    @GlobalTransactional(rollbackFor = Exception.class)
    public int auditCldMaterialAllocate(CldMaterialAllocate cldMaterialAllocate) {
        CldMaterialAllocateVo wareAllocate = cldMaterialAllocateMapper.selectCldMaterialAllocateByMaterialAllocateId(cldMaterialAllocate.getMaterialAllocateId());
        if (wareAllocate == null) {
            throw new RuntimeException("物资调拨单查询失败");
        }
        if(wareAllocate.getApproveStatus() == 0){
            wareAllocate.setApproveStatus(cldMaterialAllocate.getApproveStatus());
            wareAllocate.setApproveName(SecurityUtils.getUsername());
            wareAllocate.setApproveId(SecurityUtils.getUserId());
            wareAllocate.setApproveTime(DateUtils.getNowDate());
            if (wareAllocate.getApproveStatus() == 2) {
                wareAllocate.setRejectTime(DateUtils.getNowDate());
                wareAllocate.setRejectReason(cldMaterialAllocate.getRejectReason());
            }
            // 审核通过时修改库存数量
            if (wareAllocate.getApproveStatus() == 1) {
                cldMaterialAllocate.setIsConfirm(1L);
                cldMaterialAllocate.setConfirmTime(DateUtils.getNowDate());
                // 商品库存信息
                ErpWareCommodityNumber query = new ErpWareCommodityNumber();
                if (wareAllocate.getDetailsList() != null && !wareAllocate.getDetailsList().isEmpty()) {

                    wareAllocate.getDetailsList().forEach(item -> {
                        // 根据商品id和调出仓库id查询对应库存数据
                        query.setWareId(wareAllocate.getMaterialOutId());
                        query.setCommodityId(item.getCommodityId());
                        ErpWareCommodityNumber out = remoteWareService.selectByCommodityIdAndWareId(query, SecurityConstants.INNER);
                        // 根据调拨数量进行库存相减
                        if (out.getCommodityNumber() < item.getMaterialAllocateNumber()) {
                            throw new RuntimeException("("+item.getCommodityName1()+")仓库库存数量小于调拨数量,调拨单通过失败!");
                        }
                    });

                    wareAllocate.getDetailsList().forEach(item -> {
                        // 根据商品id和调出仓库id查询对应库存数据
                        query.setWareId(wareAllocate.getMaterialOutId());
                        query.setCommodityId(item.getCommodityId());
                        ErpWareCommodityNumber out = remoteWareService.selectByCommodityIdAndWareId(query, SecurityConstants.INNER);
                        out.setCommodityNumber(out.getCommodityNumber() - item.getMaterialAllocateNumber());
                        remoteWareService.updateErpWareCommodityNumber(out, SecurityConstants.INNER);
                        // 新增库存商品变更记录信息
                        ErpCommodityStockAlter erpCommodityStockAlter = StockCommodityAlterUtils.AssemblyInfo(item.getCommodityId(), BigDecimal.valueOf(item.getCommodityNumber()).negate(), "3", wareAllocate.getMaterialOutId());
                        remoteCommodityService.addWare(erpCommodityStockAlter, SecurityConstants.INNER);
                        // 根据商品id和调入仓库id查询对应库存数量
                        query.setWareId(wareAllocate.getMaterialInId());
                        ErpWareCommodityNumber in = remoteWareService.selectByCommodityIdAndWareId(query, SecurityConstants.INNER);
                        if (in == null) {
                            in = new ErpWareCommodityNumber();
                            in.setWareId(wareAllocate.getMaterialInId());
                            in.setCommodityId(item.getCommodityId());
                            in.setCommodityNumber(item.getMaterialAllocateNumber());
                            remoteWareService.insertErpWareCommodityNumber(in, SecurityConstants.INNER);
                        } else {
                            in.setCommodityNumber(in.getCommodityNumber() + item.getMaterialAllocateNumber());
                            remoteWareService.updateErpWareCommodityNumber(in, SecurityConstants.INNER);
                        }
                        // 新增库存商品变更记录信息
                        erpCommodityStockAlter = StockCommodityAlterUtils.AssemblyInfo(item.getCommodityId(), BigDecimal.valueOf(item.getCommodityNumber()), "3", wareAllocate.getMaterialInId());
                        remoteCommodityService.addWare(erpCommodityStockAlter, SecurityConstants.INNER);
                    });
                }
            }
        }
        return cldMaterialAllocateMapper.updateCldMaterialAllocate(wareAllocate);
    }

    /**
     * 批量删除物资调拨
     *
     * @param materialAllocateIds 需要删除的物资调拨主键
     * @return 结果
     */
    @Override
    public int deleteCldMaterialAllocateByMaterialAllocateIds(Long[] materialAllocateIds) {
        if(materialAllocateIds.length != 0){
            for (Long materialAllocateId : materialAllocateIds) {
                cldMaterialAllocateDetailsMapper.deleteCldMaterialAllocateDetailsByMaterialallocateId(materialAllocateId);
            }
            return cldMaterialAllocateMapper.deleteCldMaterialAllocateByMaterialAllocateId(materialAllocateIds[0]);
        }
        return 0;
    }

    /**
     * 删除物资调拨信息
     *
     * @param materialAllocateId 物资调拨主键
     * @return 结果
     */
    @Override
    public int deleteCldMaterialAllocateByMaterialAllocateId(Long materialAllocateId) {
        return cldMaterialAllocateMapper.deleteCldMaterialAllocateByMaterialAllocateId(materialAllocateId);
    }
}
